#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#ifndef NULL
#define NULL 0
#endif


#define bool _Bool

#ifndef true
#define true              1
#endif

#ifndef false
#define false             0
#endif

typedef struct {
    void **data;
    int top;
    int size;
} Stack;

Stack *stackCreate(int stackSize)
{
    Stack *stack = (Stack *)malloc(sizeof(Stack));
    if (stack == NULL) {
        return NULL;
    }

    stack->data = (void **)malloc(sizeof(void **) * (stackSize + 1));
    memset(stack->data, 0, sizeof(void **) * (stackSize + 1));
    stack->top = -1;
    stack->size = stackSize;
    return stack;
}

void stackFree(Stack *obj)
{
    if (obj->data != NULL) {
        free(obj->data);
        obj->data = NULL;
    }
    free(obj);
    obj = NULL;
    return;
}

bool isStackEmpty(Stack *obj)
{
    return (obj->top == -1);
}

bool isStackFull(Stack *obj)
{
    return (obj->top ==  obj->size);
}

void stackPush(Stack *obj, void *data)  // 泛型接口，使用void *
{
    if (isStackFull(obj) == true) {
        return;
    }
    int top = obj->top;
    obj->data[++top] = data;
    obj->top = top;
    return;
}

void stackPop(Stack *obj)
{
    if (isStackEmpty(obj) == true) {
        return;
    }
    void *data = obj->data[obj->top];
    if (data != NULL) {
        free(data);
        data = NULL;
    }
    obj->top--;
    return;
}

void *stackTop(Stack *obj)
{
    if (isStackEmpty(obj) == true) {
        return NULL;
    }
    return (obj->data[obj->top]);
}

void stackClear(Stack *obj)
{
    if (isStackEmpty(obj) == true) {
        return;
    }
    for (int i = 0; i <= obj->top; i++) {
        void *data = obj->data[i];
        if (data != NULL) {
            free(data);
            data = NULL;
        }
    }
    obj->top = -1;
    return;
}

void stackPushInt(Stack *obj, int value)
{
    int *node = (int *)malloc(sizeof(int));
    *node = value;
    stackPush(obj, node);
    return;
}

int stackTopInt(Stack *obj)
{
    if (isStackEmpty(obj) == true) {
        return -1;
    }
    return *(int *)(obj->data[obj->top]);    
}

void stackPushStr(Stack *obj, char *str, int strSize)
{
    char *node = (char *)malloc(sizeof(char) * (strSize + 1));
    memcpy(node, str, strSize);
    node[strSize] = '\0';
    stackPush(obj, node);
    return;
}

char *stackTopStr(Stack *obj)
{
    if (isStackEmpty(obj) == true) {
        return NULL;
    }
    return (char *)(obj->data[obj->top]);    
}
void stackPrint(Stack *obj) 
{
    for (int i = 0; i <= obj->top; i++) {
        printf("%s\n", obj->data[i]);
    }    
}

char * simplifyPath(char * path){
    int len = strlen(path);
    char *ans = malloc(sizeof(char) * (len + 1));
    Stack *stack = stackCreate(len);
    char *token = strtok(path, "/");
    int ret;
    while (token != NULL) {
        ret = strcmp(token, ".");
        if (ret == 0) {
            token = strtok(NULL, "/");
            continue;
        }
        ret = strcmp(token, "..");
        if (ret == 0 && !isStackEmpty(stack)) {
            stackPop(stack);
            token = strtok(NULL, "/");
            continue;
        }
        len = strlen(token);
        stackPushStr(stack, token, len);
        /* Get next token: */
        token = strtok(NULL, "/");
    }
    len = 0;
    
    int count = 0;
    for (int i = 0; i <= stack->top; i++) {
        ans[len++] ='/';
        char *data = stack->data[i];
        if (data != NULL) {
            strncpy(ans + len, data, sizeof(data));
            len += sizeof(data);
            free(data);
            data = NULL;
            len++;
        }
        
    }
    ans[len] = '\0';
    stackFree(stack);
    
    return ans;
}
int main()
{
    char input[] = "/a/./b/../../c/";
    char *ans = simplifyPath(input);
    return 1;
}
